#!/usr/bin/python3.6
# -*- coding: utf-8 -*-
import os
import sys
import re
import time
from git import Repo


def getBranchNames(repo):
    ret = []
    for b in repo.branches:
        ret.append(b.name)
    return ret


def cntCodeLines(name, repo, startTimeStr="2020-1-1", endTimeStr="2021-01-22"):
    fileName = name
    if "@" in name:
        prefix,name=name.split("@",1)
        fileName=prefix+"_"+name+".record"
    startTime = int(time.mktime(time.strptime(startTimeStr, "%Y-%m-%d")))
    endTime = int(time.mktime(time.strptime(endTimeStr, "%Y-%m-%d")))
    # print(f"{startTime} ~ {endTime}")
    branches = getBranchNames(repo)
    dirFilter = ["numpy","CImg.h","xslab_cloud_front2", "UnityWorkSpaces", ".vs", "target", "out", "kaldi", "boost", ".vscode", "include", "bin",
                 "x64", "lib", "depLibs", "node_modules", "vcpkg", "vcpkgo", "vcpkg3", "Release", "tempData", "tmpData", "Resources", "GeneratedFiles"]
    tempReStr = 'include'
    for dir in dirFilter:
        tempReStr = tempReStr + "|"+dir
    ignoreMatch = re.compile(r'.*?(' + tempReStr + ').*?', re.I)
    cppMath = re.compile(r'.*?\.(cpp|cc|h{1,})$', re.I)
    jsMath = re.compile(r'.*?\.vue$', re.I)
    javaMath = re.compile(r'.*?\.java$', re.I)
    pyMath = re.compile(r'.*?\.py$', re.I)
    addCnt = 0
    delCnt = 0
    hexs = ["4053da79c33124acd0db09de377bad6b2cad78f0","1e1f81a480f2f44ed400dc3d2b7c200755d0c5c1"]
    results = []
    record = open(fileName, 'w')
    for b in branches:
        pageNum = 0
        pageSize = 50
        flag = True
        # print(f"{b} {addCnt} {delCnt}")
        while flag:
            commits = list(repo.iter_commits(
                b, max_count=pageSize, skip=pageNum*pageSize))
            pageNum = pageNum + 1
            if len(commits) == 0:
                break
            for commit in commits:
                hexsha = commit.hexsha
                if hexsha in hexs:
                    flag = False
                    break
                hexs.append(hexsha)
                ctime = commit.committed_date
                if not (ctime >= startTime and ctime <= endTime):
                    continue
                msg = commit.message
                files = commit.stats.files
                for file in files:
                    if ignoreMatch.match(file):
                        continue
                    # match
                    val = files[file]
                    insertions = val["insertions"]
                    deletions = val["deletions"]
                    fileType = "?"
                    if cppMath.match(file):
                        fileType = "cpp"
                    elif javaMath.match(file):
                        fileType = "java"
                    elif jsMath.match(file):
                        fileType = "js"
                    elif pyMath.match(file):
                        fileType = "py"
                    if fileType != "?":
                        addCnt += insertions
                        delCnt += deletions
                        #if insertions >= 500 or deletions >=500:
                        #    print(f"{file} {val}")
                        realTime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(ctime))
                        record.write(
                            f"{ctime} {fileType} {insertions} {deletions} {file} {hexsha} {name} {b} {realTime}\n")
                    else:
                        #print(f"{file} {val}")
                        pass

    print(f"addCnt:{addCnt} delCnt:{delCnt} total:{addCnt-delCnt}")
    record.close()


if __name__ == "__main__":
    if len(sys.argv) < 5:
        exit(0)
    repoPath = sys.argv[1]
    recordFileName = sys.argv[2]
    startTime = sys.argv[3]
    endTime = sys.argv[4]
    # "D:\\lfxsProjects\\XsNet"
    repo = Repo(repoPath)
    if not repo.bare:
        cntCodeLines(recordFileName, repo, startTime, endTime)
    else:
        print(sys.argv)

